package com.bsi.core.validate.handler;
/*
 * Author: liusongs
 * Date: 2019/10/26 10:37
 * Content: 校验处理接口，可以自定义扩展(默认使用DefaultValidateHandler)
 */

import com.bsi.core.validate.rule.Validate;
import com.bsi.core.validate.rule.ValidateRule;
import com.google.common.collect.Lists;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

public interface ValidateHandler {
    // 存放当前被spring管理的所有的验证处理类
    Map<String, ValidateRule> VALIDATEHANDLER_LIST = new HashMap<>(16);

    // 处理器方法
    boolean handler(Object entity);

    /**
     * 获取传入类的所有属性包含父类的属性
     *
     * @param clazz 需要获取所有属性的类
     * @return
     */
    default List<Field> getHasValidateFields(Class<? extends Object> clazz) {
        Assert.notNull(clazz, "[ValidateRuleHandler.getAllField]->参数不能为空！");
        Field[] declaredFields = clazz.getDeclaredFields(); // 获取本类的属性
        Field[] declaredFields1 = clazz.getSuperclass().getDeclaredFields(); //获取父类的属性
        List<Field> fields = Lists.newArrayList();
        List<Field> superFields = Lists.newArrayList();
        if (Objects.nonNull(declaredFields)) {
            fields.addAll(Arrays.asList(declaredFields));
        }
        if (Objects.nonNull(declaredFields1)) {
            superFields.addAll(Arrays.asList(declaredFields1));
        }
        // 进行去重合并
        Map<String, List<Field>> collect = fields.stream().collect(Collectors.groupingBy(Field::getName)); // 将属性名作为key值进行匹配
        superFields = superFields.stream().filter(a -> {
            if (!CollectionUtils.isEmpty(collect)) {
                if (collect.get(a.getName()) != null) {  //说明属性重复了,过滤这条数据
                    return true;
                }
            }
            return false;
        }).collect(Collectors.toList());
        // 合并两个list
        superFields.addAll(fields);
        // 过滤掉没有带@validate注解的类
        List<Field> resultList = superFields.stream().filter(field -> {
            return field.getAnnotation(Validate.class) == null ? false : true;
        }).collect(Collectors.toList());
        return resultList;
    }
}
